package com.yeziji.config.rabbitMq;

import com.yeziji.common.business.dataMessage.entity.DataMessageRecordEntity;
import com.yeziji.common.business.dataMessage.service.DataMessageRecordService;
import com.yeziji.common.rabbitMq.RabbitMqTopicHandler;
import com.yeziji.config.EnvHolder;
import com.yeziji.constant.DataSyncStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

import javax.annotation.Resource;

/**
 * rabbit mq 消息确认回调
 *
 * @author hwy
 * @since 2024/10/26 18:17
 **/
@Slf4j
public class RabbitMqConfirmCallback implements RabbitTemplate.ConfirmCallback {
    @Resource
    private DataMessageRecordService dataMessageRecordService;

    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String message) {
        log.info("[{}] confirm message: {}:{}", ack, correlationData, message);
        if (correlationData == null) {
            log.error("correlation data is null !!!");
            return;
        }

        // 从 return 中获取对应的队列信息
        ReturnedMessage returned = correlationData.getReturned();
        if (returned != null) {
            String exchange = returned.getExchange();
            String routeKey = returned.getRoutingKey();
            // 获取主题处理器
            RabbitMqTopicHandler rabbitMqHandler = EnvHolder.getAsRabbitMqHandler(exchange, routeKey);
            if (rabbitMqHandler != null) {
                rabbitMqHandler.confirm(ack, correlationData, message);
                return;
            } else {
                // 判断是否是发送到指子客户端，如果是的话，这里如果 ack 为 true 说明消息已经传递到了(route 和 exchange 必须规范一致）
                int routerIndex = routeKey.indexOf('.');
                if (!routeKey.substring(routerIndex).equals(exchange.substring(routerIndex))) {
                    String id = correlationData.getId();
                    DataMessageRecordEntity record = dataMessageRecordService.getByFlagId(id);
                    if (record != null) {
                        record.setStatus(ack ? DataSyncStatusEnum.SUCCESS.getCode() : DataSyncStatusEnum.FAILED.getCode());
                        dataMessageRecordService.updateById(record);
                        return;
                    }
                }
            }
        }
        log.warn("confirm returned is not found handler: {}", returned);
    }
}